//
//  CustRecordViewController.m
//  iHealthEHR
//
//  Created by Joseph Ayo Akinyele on 3/30/10.
//  Copyright 2010 __MyCompanyName__. All rights reserved.
//

#import "CustRecordViewController.h"


@implementation CustRecordViewController
@synthesize ccrSections, ccrCategoryKey;
@synthesize ccrEntries, jhu, gh, cpabe;

- (id)initWithStyle:(UITableViewStyle)style {
    // Override initWithStyle: if you create the controller programmatically and want to perform customization that is not appropriate for viewDidLoad.
    if (self = [super initWithStyle:style]) {
		ccrSections = [[NSArray alloc] initWithObjects:@"Demographics", @"Conditions", @"Medications",
					   @"Allergies", @"Procedures", @"Test Results", @"Immunizations", @"Insurance", nil];
		ccrCategoryKey = [[NSArray alloc] initWithObjects:@"DEMOGRAPHICS", @"CONDITION", @"MEDICATION",
						  @"ALLERGY", @"PROCEDURE", @"LABTEST", @"IMMUNIZATION", @"PAYER", nil];
		ccrImageKey = [[NSArray alloc] initWithObjects:@"People-64.png", @"StethoBleu-64.png", @"Pills-64.png", 
						  @"Genetics-64.png", @"Case-64.png", @"Caducee-64.png", @"Seringue-64.png", @"HealthShield-64.png", nil];
		ccrCacheImage = [[NSMutableArray alloc] init];
		for(int i = 0; i < [ccrImageKey count]; i++) {
			UIImage *image = [UIImage imageNamed:[ccrImageKey objectAtIndex:i]];
			[ccrCacheImage insertObject:image atIndex:i];
		}		
    }
    return self;
}

- (void)viewDidLoad {
	//create two buttons, add them to an array and load them in the toolbar
	UIBarButtonItem *newButton = [[UIBarButtonItem alloc] initWithTitle:@"JHMI Info" style:UIBarButtonItemStyleBordered target:self action:@selector(loadinfo)];
	
	NSArray *buttons = [[NSArray alloc] initWithObjects:newButton, nil];
	// each view controller has its own toolbar that can be set appropriately.
	[self setToolbarItems:buttons];
	[newButton release];
	[buttons release];
	
	if(cpabe == nil) {
		cpabe = [[CPABEInterface alloc] init];
		[cpabe Initialize];
		[cpabe ReadParameters];
		
		/* temporary */
		[cpabe RetrieveKey:nil with:nil];
		
		if(detailedView == nil) {
			detailedView = [[DetailedViewController alloc] initWithNibName:nil bundle:nil];
			detailedView.ptrToCPabe = cpabe;
		}
		
	}
	
    // Uncomment the following line to display an Edit button in the navigation bar for this view controller.
    // self.navigationItem.rightBarButtonItem = self.editButtonItem;
	self.navigationItem.rightBarButtonItem = [[[UIBarButtonItem alloc] initWithTitle:@"Logout" style:UIBarButtonItemStylePlain 
																			  target:self action:@selector(logout)] autorelease];
	[super viewDidLoad];
}

-(void)viewWillAppear:(BOOL)animated
{
	[self.navigationController setToolbarHidden:NO];	
	[super viewWillAppear:animated];
}

-(void) loadinfo
{
	// if mvc is active ViewController, then do nothing!
	NSString *title = @"About Us";
	
	if(info == nil) {
		info = [[MedsViewController alloc] initWithNibName:@"MedsViewController" bundle:nil];
	}	
	info.title = title;
	info.curCategory = @"hospital";
	[self.navigationController pushViewController:info animated:YES];
}


/*
- (void)viewWillAppear:(BOOL)animated {
    [super viewWillAppear:animated];
}
*/
/*
- (void)viewDidAppear:(BOOL)animated {
    [super viewDidAppear:animated];
}
*/
/*
- (void)viewWillDisappear:(BOOL)animated {
	[super viewWillDisappear:animated];
}
*/
/*
- (void)viewDidDisappear:(BOOL)animated {
	[super viewDidDisappear:animated];
}
*/

/*
// Override to allow orientations other than the default portrait orientation.
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
    // Return YES for supported orientations
    return (interfaceOrientation == UIInterfaceOrientationPortrait);
}
*/

- (void)didReceiveMemoryWarning {
	// Releases the view if it doesn't have a superview.
    [super didReceiveMemoryWarning];
	
	// Release any cached data, images, etc that aren't in use.
}

- (void)viewDidUnload {
	// Release any retained subviews of the main view.
	// e.g. self.myOutlet = nil;
}


#pragma mark Table view methods

- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
    return 1;
}


// Customize the number of rows in the table view.
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
    return [ccrSections count];
}


// Customize the appearance of table view cells.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
    static NSString *ProfileCellIdentifier = @"ProfileCellIdentifier";
    
    ProfileCell *cell = (ProfileCell *)[tableView dequeueReusableCellWithIdentifier:ProfileCellIdentifier];
    if (cell == nil) {
        //cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease];
		// load nib life
		NSArray *nib = [[NSBundle mainBundle] loadNibNamed:@"ProfileCell" 
													 owner:self 
												   options:nil];
		// retrieve cell object in nib file.
		cell = [nib objectAtIndex:0];
    }
    
    // Set up the cell...
	NSUInteger row = [indexPath row];
	cell.section.text = [ccrSections objectAtIndex:row];
	// get number of entires in this specific CCR category
	cell.item.text = [self getItemCount:[ccrCategoryKey objectAtIndex:row]];
	cell.imageView.image = [ccrCacheImage objectAtIndex:row];
    return cell;	
}


- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
    // Navigation logic may go here. Create and push another view controller.
	// AnotherViewController *anotherViewController = [[AnotherViewController alloc] initWithNibName:@"AnotherView" bundle:nil];
	// [self.navigationController pushViewController:anotherViewController];
	// [anotherViewController release];
	NSString *selSection = [ccrCategoryKey objectAtIndex:[indexPath row]];
	if([selSection isEqualToString:@"DEMOGRAPHICS"]) {
		NSLog(@"[TODO: Display demographics? For now, NO!]");
		return;
	}
	
	NSArray *entries = [self getEntryByCategory:selSection];
		
	if([entries count] > 0) {
		SEL myOptions = @selector(myCCROptionsJHU);
		detailedView.ccrObjects = entries;
		detailedView.title = [ccrSections objectAtIndex:[indexPath row]];
		detailedView.ccrSubSection = selSection; // may need to pass on to WebView?
		detailedView.LoggedInThruGoogleHealth = NO;
		detailedView.selTarget = self;
		detailedView.selFunction = myOptions;
		[self.navigationController pushViewController:detailedView animated:YES];		
	}
	[entries release];
}


/*
// Override to support conditional editing of the table view.
- (BOOL)tableView:(UITableView *)tableView canEditRowAtIndexPath:(NSIndexPath *)indexPath {
    // Return NO if you do not want the specified item to be editable.
    return YES;
}
*/


/*
// Override to support editing the table view.
- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath {
    
    if (editingStyle == UITableViewCellEditingStyleDelete) {
        // Delete the row from the data source
        [tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:YES];
    }   
    else if (editingStyle == UITableViewCellEditingStyleInsert) {
        // Create a new instance of the appropriate class, insert it into the array, and add a new row to the table view
    }   
}
*/


/*
// Override to support rearranging the table view.
- (void)tableView:(UITableView *)tableView moveRowAtIndexPath:(NSIndexPath *)fromIndexPath toIndexPath:(NSIndexPath *)toIndexPath {
}
*/


/*
// Override to support conditional rearranging of the table view.
- (BOOL)tableView:(UITableView *)tableView canMoveRowAtIndexPath:(NSIndexPath *)indexPath {
    // Return NO if you do not want the item to be re-orderable.
    return YES;
}
*/

/* upload 
 
 */
- (void)alertView:(UIAlertView *)alertView willDismissWithButtonIndex:(NSInteger)buttonIndex
{
	LoginPrompt *prompt = (LoginPrompt *) alertView;
    if (buttonIndex != [alertView cancelButtonIndex])
    {
        // NSString *entered = [(LoginPrompt *)alertView enteredText];
		NSString *username = prompt.username.text;
		NSString *password = prompt.password.text;
		NSString *profile  = prompt.profile.text;
		/* TODO: validate input from alertview */
		
 		NSLog(@"Username => '%@'", username);
		NSLog(@"Password => '%@'", password);
		NSLog(@"Profile => '%@'", profile);
		if(gh == nil) {
			gh = [[GoogleHealth alloc] init];
			gh.gUsername = username;
			gh.gPassword = password;
			// get profile name from user too
			[gh useGoogleHealthProduction:YES];
			[gh fetchMyFeeds:profile withDelegate:self andCallback:nil];		
		}
    }
	[prompt.username resignFirstResponder];
	[prompt.password resignFirstResponder];
	[prompt.profile resignFirstResponder];	
}

-(void) loginSuccessfulandFeedsSet
{
	/* Should be a preference, I know! */
	BOOL uploadEncrypted = [UserSettings getEncryptedUpload];
#ifdef LOG_DEBUG	
	NSLog(@"Login successful! Now upload contents of section.");
	NSLog(@"mProfileFeed: %@", [gh.mProfileFeed description]);
	NSLog(@"mRegisterFeed: %@", [gh.mRegisterFeed description]);
#endif	
	/* Loads the detailedView CCR objects and section. Performs the upload to Google
	 Health. */
	
	NSArray *entries = detailedView.ccrObjects;
#ifdef LOG_DEBUG	
	printf("There are %i entries\n", [entries count]);
	NSLog(@"Section is %@", detailedView.ccrSubSection);
#endif
 	SEL callback = @selector(postTicket:finishedWithEntry:error:);
	
	lastUpload = NO;
	// means we decrypt
	for(int i = 0; i < [entries count]; i++) {
		if(i == ([entries count] - 1)) {
			NSLog(@"Last upload for section...");
			lastUpload = YES;
		}

		CCRObject *c = [entries objectAtIndex:i];
		/* plaintext or encrypted? GLOBAL PREFERENCE: Right now assume plaintext */
		if(uploadEncrypted) { /* upload encrypted */
			if(c.encryptedXmlElement != nil) {
				/* must free ghCCR */
				NSXMLElement *ghCCR = [c transformEncryptedForGoogleHealth:cpabe];
				NSLog(@"Uploading Encrypted: %@", c.item);
				GDataContinuityOfCareRecord *ccr = [XMLParser createCCRDocument:ghCCR];
				[gh sendUpdate:ccr withDelegate:self andCallback:callback];
				[ccr release];	
				[ghCCR release];
			}
			else {
				/* if element was not originally encrypted */
				// either encrypt or for now just upload as is?
				/* For encryption, need a way for user to specify policy or suggest policies to the user
				   and allow them to modify appropriately.
				 */
				if(c.plaintextXmlElement != nil) {
					NSLog(@"Uploading as is: %@", c.item);
					GDataContinuityOfCareRecord *ccr = [XMLParser createCCRDocument:c.plaintextXmlElement];
					[gh sendUpdate:ccr withDelegate:self andCallback:callback];
					[ccr release];
				}				
			}
		}
		else { /* upload plaintext */
			// make sure record already decrypted
			if([CCRObject isThisEntryEncrypted:c.plaintextXmlElement] == YES) {
				// decrypt plaintext record first.
				NSLog(@"Decrypting record first.");
				[c decrypt:cpabe];
			}
			
			if(c.plaintextXmlElement != nil) {
				NSLog(@"Uploading Plaintext: %@", c.item);
				GDataContinuityOfCareRecord *ccr = [XMLParser createCCRDocument:c.plaintextXmlElement];
				[gh sendUpdate:ccr withDelegate:self andCallback:callback];
				[ccr release];
			}
		}
	}		
	
	NSLog(@"Continue...");
	
	/* transform if encrypted */
	
	/* upload in clear if encrypted */
}

// This method is called by Google Health when our upload is successful.
-(void) uploadSuccessful
{	
	if(lastUpload == YES) {
		NSString *msg = [NSString stringWithFormat:@"Completely uploaded the '%@' section of your CCR.", detailedView.ccrSubSection];
		[gh sendNotice:@"Uploaded NEW entry" withContent:msg];
		/* reset */
		lastUpload = NO;
	}
	NSLog(@"One upload sent.");
}

-(void) uploadFailed:(NSError *) error stage:(NSString *) message
{
	NSLog(@"uploadFailed:");
	NSLog(@"Error: %@", [error description]);
	NSLog(@"Message: %@", message);
	return;
}

-(void) loginFailed:(NSError *) error stage:(NSString *) message
{
	NSLog(@"Login failed.");
	if(error != nil)
		NSLog(@"Description: %@", [error description]);
	NSLog(@"Stage: %@", message);
	
	/* start over */
	[gh release];	
}

-(void) actionSheet:(UIActionSheet *) actionSheet clickedButtonAtIndex:(NSInteger) buttonIndex
{
	// printf("User Pressed Button %d\n", buttonIndex);
/*	if(buttonIndex == 0) {
		NSLog(@"View Help here?");
	}
	else */
	if(buttonIndex == 0) { /* DECRYPT OPTION */
		NSArray *entries = detailedView.ccrObjects;
		BOOL _decrypt = NO;
#ifdef LOG_DEBUG		
		printf("There are %i entries\n", [entries count]);
		NSLog(@"Section is %@", detailedView.ccrSubSection);
#endif
		NSString *status = [[NSString alloc] initWithFormat:@"Decrypting %@ section...", detailedView.ccrSubSection]; 
		[detailedView showTheProgress:status];
		[status release];
		
		// means we decrypt
		for(int i = 0; i < [entries count]; i++) {
			CCRObject *c = [entries objectAtIndex:i];
			if([c decrypt:cpabe] == YES) {
				NSString *text = [DetailedViewController parseDescription:c ofCCR:detailedView.ccrSubSection];
				c.item = text;
				c.editDate = [NSDate date];
				// NSLog(@"New text = %@", text);
				_decrypt = YES;
				detailedView.UserSelectedDecryption = YES;
				detailedView.ptrToCPabe = cpabe;
			}
		}
		
		if(!_decrypt) {
			[CCRObject popUpNotice:@"Decrypt" withMessage:@"Nothing to decrypt."];	
		}
	}
	else if(buttonIndex == 1) { /* UPLOAD RECORD TO GH */
		// means we upload all records to google health?
		if(gh == nil) {
			LoginPrompt *prompt = [LoginPrompt alloc];
			prompt = [prompt initWithTitle:@"Login" message:@"Enter login information" delegate:self cancelButtonTitle:@"Cancel" okButtonTitle:@"Okay"];
			[prompt show];
			[prompt release];
		}
		else {
			[self loginSuccessfulandFeedsSet];
		}
		// check if already logged in?		
		// if so, continue upload
		// if not, ask for user/pass via AlertView.
		// authenticate, also let user know if this fails
		// take encrypted XML and transform for googles servers
		/*for (int i = 0; i < [entries count]; i++) {
			CCRObject *c = [entries objectAtIndex:i];
			if(c.encryptedXmlElement != nil) {
				// transform encrypted XML 
				NSLog(@"Transforming for GH");
				[c transformEncryptedForGoogleHealth];
				NSLog(@"Done transformation, ready to upload.");
			}
			
			// getUserOption (TODO: Load from application bundle) 
		} */
		// upload resulting xml
		// ?
	}
	
	// reload data view
	[detailedView.tableView reloadData];
	[actionSheet release];
}

-(void) logout
{
	NSLog(@"Are you sure?");
	[self.navigationController popToRootViewControllerAnimated:YES];
}

// load options for user...
-(void) myCCROptionsJHU
{
	/* Support decryption (IMPLEMENT NEXT), upload to GH (DONE), and edit policy (FUTURE WORK) */
	UIActionSheet *menu = [[UIActionSheet alloc]
							initWithTitle:@"Options" 
							delegate:self 
							cancelButtonTitle:@"Cancel" 
//							destructiveButtonTitle:@"Help" 
						    destructiveButtonTitle:nil 
							otherButtonTitles:@"Decrypt All", @"Upload to GH", nil];
	[menu showInView:detailedView.view];
}


- (void)dealloc {
	[cpabe CleanUp];
	[cpabe release];
	[ccrSections release];
	[ccrEntries release];
	[ccrImageKey release];
	[ccrCategoryKey release];
	[ccrCacheImage release];
	[jhu release];
	[gh release];
	[info release];
    [super dealloc];
}

#pragma mark -
#pragma mark Helper Methods

-(NSString *) getItemCount:(NSString *)section
{
	// in case entries arent set.	
	CCRObject *entry;
	
	int maxCount = [ccrEntries count];
	int itemCount = 0;
	for(int i = 0; i < maxCount; i++) {
		// Retrieve each profile 
		entry = [ccrEntries objectAtIndex:i];
		NSString *ccrTerm = [entry ccrsection];
		if([ccrTerm isEqualToString:section]) {
			itemCount++;
		}		
	}
	
	return [NSString stringWithFormat:@"%d items", itemCount];
}

-(NSArray *) getEntryByCategory:(NSString *)section
{
	CCRObject *entry;
	int max = [ccrEntries count];
	NSMutableArray *_array = [[NSMutableArray alloc] init];
	for(int i = 0; i < max; i++) {
		entry = [ccrEntries objectAtIndex:i];
		if([[entry ccrsection] isEqualToString:section]) {
			// parse Description here? 
			if([entry.item isEqualToString:@"Empty"]) {
				NSString *text = [self parseDescription:entry ofCCR:section];
				if(text != nil) {
					entry.item = text;
					entry.editDate = [NSDate date];
					NSLog(@"Print XML => %@", entry.XmlElement);
				}
			}
			// add entry of this object into array
			[_array addObject:entry];
		}	
	}
	
	if([_array count] > 0) {
		return _array;
	}
	
	[_array release];
	return nil;
}

// changes the name of the ccr object item and description
// if data contains encrypted XML tags, mark it so.
-(NSString *) parseDescription:(CCRObject *) object ofCCR:(NSString *) section
{
//	XMLParser *xmlParser = [[XMLParser alloc] init];
	NSString *text = nil;
	NSEnumerator *eN;
	NSXMLElement *xml = [object getPlainText];
	
	NSArray *n = [xml elementsForName:@"Body"];
	NSXMLNode *e = [n objectAtIndex:0];	
	NSArray *desc;
	if([section isEqualToString:@"MEDICATION"] ||
	   [section isEqualToString:@"IMMUNIZATION"]) {
		desc = [XMLParser findChild:e withTag:@"ProductName"];
	}
	else if([section isEqualToString:@"PAYER"]) {
		desc = [XMLParser findChild:e withTag:@"Type"];
	}
	else {
		desc = [XMLParser findChild:e withTag:@"Description"];
	}

	if([section isEqualToString:@"ALLERGY"])
		eN = [[[desc objectAtIndex:1] children] objectEnumerator];		
	else
		eN = [[[desc objectAtIndex:0] children] objectEnumerator];
	
	NSXMLNode *tmp;
	while(tmp = [eN nextObject]) {
		if([[tmp name] isEqualToString:@"Text"]) {
			NSLog(@"Text => %@", [tmp stringValue]);
			text = [tmp stringValue];
		}
	}
	
	// NSLog(@"parse Description => %@", xml);
	[desc release];
//	[xmlParser release];
	return text;
}


@end

